package com.example.douyin.service;

import com.example.douyin.vo.Content;
import com.example.douyin.vo.DouyinMessageBody;
import com.example.douyin.vo.RespData;
import lombok.extern.slf4j.Slf4j;
import net.sf.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import javax.servlet.http.HttpServletRequest;
import java.util.Map;

/**
 * @author: dangwen
 * @createDate: 2020/12/8
 */
@Slf4j
@Component
public class DouyinOpenService {
    @Value("${douyin.open.domain:https://open.douyin.com/}")
    private String domain;
    @Value("${douyin.open.clientKey:awvo8dutvmjn6n9b}")
    private String clientKey;
    @Value("${douyin.open.clientSecret:c155a4dc4526bcbf4ab5198ae51da090}")
    private String clientSecret;
    @Value("${douyin.open.responseType:code}")
    private String responseType;
    @Value("${douyin.open.scope:enterprise.data,enterprise.im,user_info}")
    private String scope;
    @Value("${douyin.open.redirectUrl:myDomain.com}")
    private String redirectUrl;

    @Autowired
    private RestTemplate restTemplate;
    @Autowired
    private ApplicationEventPublisher applicationEventPublisher;

    /**
     * 用来构建获取code的请求url
     *
     * @return
     */
    public String buildUrl() {
        StringBuilder builder = new StringBuilder(domain);
        builder.append("platform/oauth/connect?client_key=").append(clientKey).append("&response_type=").append(responseType)
                .append("&scope=").append(scope).append("&redirect_uri=http://").append(redirectUrl);
        return builder.toString();
    }

    /**
     * 扫码授权，获取access_token&&open_id
     *
     * @param request
     */
    public void getAccessToken(HttpServletRequest request) {
        Map<String, String[]> parameterMap = request.getParameterMap();
        String code = parameterMap.get("code")[0];
        StringBuilder tokenUrl = new StringBuilder(domain);
        tokenUrl.append("oauth/access_token?client_key=").append(clientKey).append("&client_secret=").append(clientSecret)
                .append("&code=").append(code).append("&grant_type=authorization_code");
        long l1 = System.currentTimeMillis();
        log.info("you are ready to send a request to douyin, code:{}, requestUrl:{}， now the timeStamp is: {}", code, tokenUrl, l1);
        // 获取access_token
        ResponseEntity<RespData> accessTokenData = restTemplate.getForEntity(tokenUrl.toString(), RespData.class);
        log.info("get access_token from douyin, ResponseEntity:{}, it took {} millis", accessTokenData.toString(), System.currentTimeMillis() - l1);
        RespData accessTokenBody = accessTokenData.getBody();
        Map accessTokenBodyData = accessTokenBody.getData();
        if ((Integer) accessTokenBodyData.get("error_code") == 0) {
            String open_id = accessTokenBodyData.get("open_id").toString();
            String access_token = accessTokenBodyData.get("access_token").toString();
            String refresh_token = accessTokenBodyData.get("refresh_token").toString();

            StringBuilder infoUrl = new StringBuilder(domain);
            infoUrl.append("oauth/userinfo?open_id=").append(open_id).append("&access_token=").append(access_token);
            long l2 = System.currentTimeMillis();
            log.info("you are ready to send a request to douyin, requestUrl:{}, now the timeStamp is: {}", infoUrl, l2);
            ResponseEntity<RespData> userInfoData = restTemplate.getForEntity(infoUrl.toString(), RespData.class);
            log.info("get user_info from douyin, ResponseEntity:{}, it took {} millis", userInfoData.toString(), System.currentTimeMillis() - l2);
            RespData userInfoDataBody = userInfoData.getBody();
            Map userInfoDataBodyData = userInfoDataBody.getData();
        } else {
            log.warn("获取access_token异常, accessTokenBody: {}", accessTokenBody);
        }

    }

    /**
     * 处理抖音发送过来的消息，使消息体符合我们需要的格式
     *
     * @param body
     */
    public Content processReceivedMessage(DouyinMessageBody body) {
        Content content = new Content();
        content.setChallenge(body.getContent().getChallenge());
        System.out.println(body.toString());
        return content;
    }

    /**
     * 回复抖音企业号发送过来的用户消息
     *
     * @param toUserId
     * @param openId
     * @param accessToken
     * @param textMsg
     */
    public void sendMessageToUser(String toUserId, String openId, String accessToken, String textMsg) {
        StringBuilder urlBuilder = new StringBuilder(domain);
        urlBuilder.append("enterprise/im/message/send").append("?open_id=").append(openId).append("&access_token=").append(accessToken);
        // net.sf.json
        JSONObject bodyMap = new JSONObject();
        String jsonString = "\"{\"text\":\"" + textMsg + "\"}\"";
        bodyMap.put("content", jsonString);
        bodyMap.put("message_type", "text");
        bodyMap.put("to_user_id", toUserId);
        long l1 = System.currentTimeMillis();
        log.info("you are ready to send a message to douyin, the url is: {}, and the requestBody is: {}, now the timeStamp is: {}", urlBuilder.toString(), bodyMap.toString(), l1);
        RespData respData = restTemplate.postForObject(urlBuilder.toString(), bodyMap, RespData.class);
        Map data = respData.getData();
        if ((Integer) data.get("error_code") == 0) {
            log.info("all right, your message has been sent to douyin server, respData: {}, it took {} millis", respData, System.currentTimeMillis() - l1);
        } else {
            log.warn("attention please, something goes wrong, respData: {}, it took {} millis", respData, System.currentTimeMillis() - l1);
        }
    }

    public Content unauthorize(DouyinMessageBody body) {
        log.info("douyin user ready to unauthorize, the messageBody is: {}", body);
        Content content = new Content();
        content.setChallenge(body.getContent().getChallenge());
        System.out.println(body.toString());
        return content;
    }

}
